<?php
/*********************************************
  Dragonfly CMS, Copyright (c) 2004 by CPGNuke Dev Team
  http://dragonflycms.org
  Released under GNU GPL version 2 or any later version

  $Source$
  $Revision$
  $Author$
  $Date$
**********************************************/

abstract class Client
{

	public static $os;
	public static $name;
	public static $version;
	public static $engine;
	public static $engineV;
	public static $isMobile;
	public static $verified;
	public static $hostname;

	protected static $ua = '';

	public static function init()
	{
		Client::name();
		if (!DF_MODE_DEVELOPER && isset($_SESSION['CLIENT']['name'])) {
			if ($_SESSION['CLIENT']['name'] !== Client::$name || $_SESSION['CLIENT']['version'] !== Client::$version) {
				Dragonfly_Net_Http::headersFlush(400, 'User agent mismatch');
			}
			Client::$name     = (string) $_SESSION['CLIENT']['name'];
			Client::$version  =  (float) $_SESSION['CLIENT']['version'];
			Client::$os       = (string) $_SESSION['CLIENT']['os'];
			Client::$engine   = (string) $_SESSION['CLIENT']['engine'];
			Client::$engineV  =  (float) $_SESSION['CLIENT']['engineV'];
			Client::$isMobile =   (bool) $_SESSION['CLIENT']['isMobile'];
			Client::$verified =    (int) $_SESSION['CLIENT']['verified'];
			Client::$hostname = (string) $_SESSION['CLIENT']['hostname'];
			return;
		}
		Client::os();
		Client::engine();
		Client::isMobile();
		$_SESSION['CLIENT']['name']     = (string) Client::$name;
		$_SESSION['CLIENT']['version']  =  (float) Client::$version;
		$_SESSION['CLIENT']['os']       = (string) Client::$os;
		$_SESSION['CLIENT']['engine']   = (string) Client::$engine;
		$_SESSION['CLIENT']['engineV']  =  (float) Client::$engineV;
		$_SESSION['CLIENT']['isMobile'] =   (bool) Client::$isMobile;
		$_SESSION['CLIENT']['verified'] =    (int) Client::$verified;
		$_SESSION['CLIENT']['hostname'] = (string) Client::$hostname;
	}

	public static function dump()
	{
		return array(
			'name'     => Client::$name,
			'os'       => Client::$os,
			'version'  => Client::$version,
			'engine'   => Client::$engine,
			'engineV'  => Client::$engineV,
			'isMobile' => Client::$isMobile,
			'verified' => Client::$verified,
			'hostname' => Client::$hostname
			);
	}
	/** Return null values on failure */
	protected static function name()
	{
		if (empty($_SERVER['HTTP_USER_AGENT'])) return;
		Client::$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
		/*
		 * swiftfox, epiphany, flock and galeon have "firefox" in their UA
		 * chimera is an on old name of camino
		 * midori, omniweb, shiira and sunrise have "safari" in their UA
		 * We don't detect MyIE2, AOL and America Online branded versions of MSIE
		 * Sylera is a Japanese Gecko based browser
		 */
		if(preg_match('#(msie) (1?[0-9](\.[0-9])?)#', Client::$ua, $match)
		|| preg_match('#(epiphany|flock|galeon|midori|omniweb|swiftfox)#', Client::$ua, $match)
		|| preg_match('#(chrome|safari|firefox|netsurf)/([0-9]+(\.[0-9]+)?)#', Client::$ua, $match)
		|| preg_match('#(crazy|maxthon|avant|webtv|ubvision|slimbrowser|swiftweasel)#', Client::$ua, $match)
		|| preg_match('#(elinks|opera|shiira|devontech|ibrowse|icab|conkeror|chimera|classilla|gnuzilla|iceweasel|iceape)#', Client::$ua, $match)
		|| preg_match('#(konqueror|voyager|links|lynx|w3m|dillo|netscape|thunderbird|camino|seamonkey|linspire|multizilla|k\-meleon|kazehakase|minimo)#', Client::$ua, $match)
		|| preg_match('#(webwasher)#', Client::$ua, $match))
		{
			Client::$name = $match[1];
			if (isset($match[2])) { Client::$version = intval($match[2]); }
			if (('opera' === Client::$name || 'safari' === Client::$name) && preg_match('#version/([0-9]+(\.[0-9]+)?)#', Client::$ua, $match)) {
				Client::$version = floatval($match[1]);
			}
		}
		/*
		 * firebird and phoenix are old names for firefox
		 * bonecho, granparadiso, minefield are develop names for firefox
		 */
		else if (preg_match('#(firebird|phoenix|bonecho|granparadiso|minefield|shiretoko)[\/ ]([0-9]+(\.[0-9]+)?)#', Client::$ua)) {
			Client::$name = 'firefox';
		}
		else if (preg_match('#^mozilla/5.+gecko/200#', Client::$ua)) {
			Client::$name = 'mozilla';
		}
	}

	/** Returns null values on failure */
	protected static function os()
	{
		if (preg_match('#(windows|mac|android|linux|bsd|sunos|syllable|irix|beos|os/2|aix|amiga|react|javafx|palm|nintendo|playstation|darwin)#', Client::$ua, $match)
		 || preg_match('#(symbian|blackberry|iphone|meego|ipad|x11)#', Client::$ua, $match))
		{
			switch ($match[1]):
				case 'win':
					Client::$os = 'windows';
					break;
				case 'iphone':
				case 'ipad':
					Client::$os = 'ios';
					break;
				default:
					Client::$os = $match[1];
					break;
			endswitch;
		}
	}

	/** Return null values on failure */
	protected static function engine()
	{
		if (preg_match('#(apachebench|dillo|gecko|khtml|presto|trident|up\.browser|webkit|libwww|java|netsurf)[\/ ]([0-9]+(\.[0-9]+)?)#', Client::$ua, $match)
		|| preg_match('#(msie|opera)[\/ ]([0-9]+(\.[0-9]+)?)#', Client::$ua, $match)) {
			/*
			 * IE9 and IE8 includes Trident version in their UA so we only look for empty ones
			 * IE8 in compatibility mode identify itClient as IE7 but leaves trident/4.0 in the UA
			 */
			if ('msie' === $match[1] || ('trident' === $match[1] && false !== strpos(Client::$ua, 'msie 7'))) {
				Client::$engine = 'trident';
				Client::$engineV = 3;
			} else {
				if ('opera' == $match[1]) { $match[1] = 'presto'; }
				Client::$engine = $match[1];
				Client::$engineV = floatval($match[2]);
			}
		}
	}

	/** Return bool */
	protected static function isMobile()
	{
		Client::$isMobile = !empty($_SERVER['HTTP_X_OPERAMINI_PHONE'])
		|| isset($_SERVER['HTTP_ACCEPT']) && false !== strpos(strtolower($_SERVER['HTTP_ACCEPT']), '/vnd.wap.') // xhtml+xml | wml
		|| Client::$os == 'android'
		|| Client::$os == 'maemo'
		|| Client::$os == 'symbian'
		|| Client::$os == 'blackberry'
		|| Client::$os == 'ios'
		|| false !== strpos(Client::$ua, 'windows ce')
		|| false !== strpos(Client::$ua, 'mobile')
		|| false !== strpos(Client::$ua, 'epoc')
		|| false !== strpos(Client::$ua, 'opera mini')
		|| false !== strpos(Client::$ua, 'opera mobi')
		|| false !== strpos(Client::$ua, 'minimo')
		|| false !== strpos(Client::$ua, 'nitro')
		|| false !== strpos(Client::$ua, 'j2me')
		|| false !== strpos(Client::$ua, 'midp-')
		|| false !== strpos(Client::$ua, 'cldc-')
		|| false !== strpos(Client::$ua, 'netfront')
		|| false !== strpos(Client::$ua, 'mot')
		|| false !== strpos(Client::$ua, 'up.browser')
		|| false !== strpos(Client::$ua, 'up.link')
		|| false !== strpos(Client::$ua, 'sony')
		|| false !== strpos(Client::$ua, 'nokia')
		|| false !== strpos(Client::$ua, 'samsung')
		|| false !== strpos(Client::$ua, 'audiovox')
		|| false !== strpos(Client::$ua, 'ericsson')
		|| false !== strpos(Client::$ua, 'panasonic')
		|| false !== strpos(Client::$ua, 'philips')
		|| false !== strpos(Client::$ua, 'sanyo')
		|| false !== strpos(Client::$ua, 'sharp')
		|| false !== strpos(Client::$ua, 'sie-')
		|| false !== strpos(Client::$ua, 'portalmmm')
		|| false !== strpos(Client::$ua, 'blazer')
		|| false !== strpos(Client::$ua, 'avantgo')
		|| false !== strpos(Client::$ua, 'danger')
		|| false !== strpos(Client::$ua, 'palm')
		|| false !== strpos(Client::$ua, 'series60')
		|| false !== strpos(Client::$ua, 'palmsource')
		|| false !== strpos(Client::$ua, 'pocketpc')
		|| false !== strpos(Client::$ua, 'smartphone')
		|| false !== strpos(Client::$ua, 'rover')
		|| false !== strpos(Client::$ua, 'ipaq')
		|| false !== strpos(Client::$ua, 'au-mic')
		|| false !== strpos(Client::$ua, 'alcatel')
		|| false !== strpos(Client::$ua, 'ericy')
		|| false !== strpos(Client::$ua, 'vodafone/')
		|| false !== strpos(Client::$ua, 'wap1.')
		|| false !== strpos(Client::$ua, 'wap2.')
		|| false !== strpos(Client::$ua, 'portable');
	}

}
Client::init();
